package com.cn.jx.configuration;

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import com.jx.annotation.PermissionsAnnot;
import com.jx.enumType.PermissionsEnum;
import com.jx.util.Utility;

/**
 * 
 * @author 姜旭
 * @version v1.11.20.2019
 * @since 
 * <p>创建时间：2019年11月24日
 * <p>功能描述：权限拦截
 * <p>官方网站：management/admin/index
 * <p>邮箱地址：524577360@qq.com
 */
@Component
@Aspect
public class PermissionsConfiguration {

	@Around("@annotation(com.jx.annotation.PermissionsAnnot)")
	public Object Permissions(ProceedingJoinPoint joinPoint) throws Throwable{
		//获取查询的key  连接点是在方法上的,所以可以强转成方法的签名信息
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
				
		Method method = joinPoint.getTarget().getClass().getMethod(signature.getName(), signature.getMethod().getParameterTypes());
		PermissionsAnnot redisCache = method.getAnnotation(PermissionsAnnot.class);
		//key为权限类型
		PermissionsEnum key=redisCache.permissionType();
		String value=redisCache.value();
		Object[] args = joinPoint.getArgs();//获取方法里的参数值
		if(args.length>0){
			//1.创建表达式
			SpelExpressionParser parser = new SpelExpressionParser();
			Expression expression = parser.parseExpression(value);
			//2.设置解析上下文(有哪些占位符以及占位符的值)
			EvaluationContext context = new StandardEvaluationContext();
			//获取方法真实参数名
			ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
			String[] parameterNames = parameterNameDiscoverer.getParameterNames(method);
			//将方法的参数名和参数值设置在解析器里
			for (int i = 0; i < parameterNames.length; i++) {
				context.setVariable(parameterNames[i], args[i]);
			}
			//获取将占位符替换成真实参数后的key
			value = expression.getValue(context).toString();
		}
		switch (key) {
		case INIT:
			//如果是超级管理员 满足INIT权限
			if(Utility.getSuperName().equals(value)) {
				Object proceed = joinPoint.proceed();//执行查询
				return proceed;
			}
			break;
		default:
			break;
		}
		return "error/nopermissions";
	}
}
